Skip to content

refactor(DF-1004): stamp $$__formVersion at write time in modifyDraft#794

Merged
mokhld merged 3 commits intomainfrom
fix/our-1004-submission-version-bug-write-time
Apr 28, 2026
Merged

refactor(DF-1004): stamp $$__formVersion at write time in modifyDraft#794
mokhld merged 3 commits intomainfrom
fix/our-1004-submission-version-bug-write-time

Conversation

@mokhld
Copy link
Copy Markdown
Contributor

@mokhld mokhld commented Apr 24, 2026

Stamping moves from read-time (getFormDefinition) to write-time (inside modifyDraft/insertDraft). Every draft mutation atomically stamps and snapshots; getFormDefinition is a pure read.

Alternative to #792.

Moves version stamping from read-time injection in getFormDefinition to
write-time stamping inside modifyDraft and insertDraft. Every draft
mutation now atomically allocates a version, stamps the definition, and
snapshots to form-versions.

Service callers no longer need to call createFormVersion after
modifyDraft. getFormDefinition reverts to a pure read. createLiveFromDraft
and createDraftFromLive inherit the stamp on copy.

Fixes the submission crash where live reads on forms with unsaved drafts
were tagged with draft-save version numbers.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors form version stamping so $$__formVersion is persisted at write-time (via modifyDraft/insertDraft and related flows) rather than injected at read-time in getFormDefinition, making reads pure and ensuring version snapshots are created atomically during draft mutations.

Changes:

  • Move $$__formVersion stamping + version snapshot creation into repository-layer draft writes (insertDraft/modifyDraft), and make getFormDefinition a pure read.
  • Update multiple draft-mutation services to stop calling createFormVersion explicitly (versioning now happens inside draft writes).
  • Add/adjust supporting APIs and tests (e.g., setFormVersion, route stamping, reinstate flow, and versioning tests).

Reviewed changes

Copilot reviewed 20 out of 20 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/routes/forms.js Switch version-definition endpoint stamping from removed injectFormVersion to stampFormVersion.
src/helpers/feedback-form/reinstate.test.js Mock version creation to accommodate new reinstate/version behavior.
src/helpers/feedback-form/reinstate.js Mirror version stamp onto Live during feedback-form reinstate.
src/api/forms/service/versioning.test.js Update expectations to reflect persisted stamp and repository setFormVersion call.
src/api/forms/service/versioning.js Refactor version creation to use shared allocation + stamping helpers and persist the stamp.
src/api/forms/service/sections.test.js Remove expectation that services explicitly call createFormVersion.
src/api/forms/service/sections.js Stop explicitly creating versions for section assignment (now handled by draft writes).
src/api/forms/service/page.js Stop explicitly creating versions for page mutations (now handled by draft writes).
src/api/forms/service/options.js Stop explicitly creating versions for option mutations (now handled by draft writes).
src/api/forms/service/migration.js Stop explicitly creating versions for draft migration updates (now handled by draft writes).
src/api/forms/service/lists.js Stop explicitly creating versions for list mutations (now handled by draft writes).
src/api/forms/service/index.test.js Remove expectations around explicit createFormVersion calls.
src/api/forms/service/index.js Remove explicit version creation in create/title update paths; keep versioning for metadata-only edits.
src/api/forms/service/definition.test.js Update tests to assert getFormDefinition returns stored definition verbatim (no injection).
src/api/forms/service/definition.js Remove read-time version injection (injectFormVersion) and stop explicit versioning calls.
src/api/forms/service/conditions.js Stop explicitly creating versions for condition mutations (now handled by draft writes).
src/api/forms/service/component.js Stop explicitly creating versions for component mutations (now handled by draft writes).
src/api/forms/repositories/helpers.js Add FORM_VERSION_METADATA_KEY, allocateDraftVersion, stampFormVersion; stamp+snapshot inside insertDraft/modifyDraft.
src/api/forms/repositories/form-definition-repository.test.js Mock metadata/versions repositories to avoid new side effects during repository tests.
src/api/forms/repositories/form-definition-repository.js Add setFormVersion to persist a version stamp onto stored definitions.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 406 to +410
const repositioned = repositionPaymentAndSummary(updated)
const validated = validate(repositioned, schema)

// Validate form definition
const draft = validate(repositioned, schema)
const versionMetadata = await allocateDraftVersion(formId, session)
const draft = stampFormVersion(validated, versionMetadata)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually @mokhld this is a good spot

Comment on lines +320 to +328
await formVersionsRepository.createVersion(
{
formId,
versionNumber: versionMetadata.versionNumber,
formDefinition: draft,
createdAt: versionMetadata.createdAt
},
session
)
Comment on lines +429 to +437
await formVersionsRepository.createVersion(
{
formId,
versionNumber: versionMetadata.versionNumber,
formDefinition: draft,
createdAt: versionMetadata.createdAt
},
session
)
mokhld added 2 commits April 24, 2026 12:10
…ing tests

Addresses Copilot review feedback on PR #794:

- modifyDraft's initial findOne now participates in the transaction
  (was reading outside the session, risking stale reads under concurrent
  draft updates). Added projection { draft: 1 } since that's all we need.
- Added two tests covering the version stamping behaviour introduced in
  modifyDraft and insertDraft (allocates version, stamps draft with
  $$__formVersion, snapshots to form-versions).
@sonarqubecloud
Copy link
Copy Markdown

Copy link
Copy Markdown
Contributor

@alexluckett alexluckett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM but let's wait for one more approval before we merge

@mokhld mokhld merged commit b57da95 into main Apr 28, 2026
12 checks passed
@mokhld mokhld deleted the fix/our-1004-submission-version-bug-write-time branch April 28, 2026 08:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants